package top.ahzy.seobench.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import top.ahzy.seobench.config.SeobenchConfig;
import top.ahzy.seobench.consts.HttpConst;
import top.ahzy.seobench.mapper.ImgInfoMapper;
import top.ahzy.seobench.model.entity.ImgInfo;
import top.ahzy.seobench.service.ImgService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
public class ImgServiceImpl implements ImgService {

    @Autowired
    private SeobenchConfig seobenchConfig;

    @Resource
    private ImgInfoMapper imgInfoMapper;

    @Override
    public ResponseEntity<InputStreamResource> getIconBase(HttpServletRequest request,String urlBase) throws IOException {
        String url = new String(Base64.decode(urlBase));
        String wetSite = getDomainFromUrl(url);

        LambdaQueryWrapper<ImgInfo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ImgInfo::getUrl, url).last("LIMIT 1");
        ImgInfo imgInfo = imgInfoMapper.selectOne(lqw);
        if (ObjUtil.isNotNull(imgInfo)) {
            return getImgResource(request,imgInfo.getImgRoute());
        }


        imgInfo = new ImgInfo();
        imgInfo.setId(IdUtil.simpleUUID());
        imgInfo.setWebsite(wetSite);
        imgInfo.setUrl(url);
        imgInfo.setImgRoute(imgInfo.getId() + ".png");
        imgInfo.setCreateTime(new Date());
        String savePath = seobenchConfig.getGetfaviconStorage() + imgInfo.getImgRoute();
        String httpString = url; // 默认获取图片
        if (!seobenchConfig.isSuffix(url)) { // 改为获取图标
            httpString = seobenchConfig.getGetfaviconUrl() + "?url=" + url + "&submitget=get+favicon";
        }

        try {
            HttpResponse response = HttpUtil.createGet(httpString, true).timeout(60000).executeAsync();
            boolean flag = response.isOk()
                    &&(HttpConst.IMAGE_ICON.equals(response.header(HttpConst.CONTENT_TYPE)) ||
                    HttpConst.IMAGE_GIF.equals(response.header(HttpConst.CONTENT_TYPE)) ||
                    HttpConst.IMAGE_JEPG.equals(response.header(HttpConst.CONTENT_TYPE)) ||
                    HttpConst.IMAGE_PNG.equals(response.header(HttpConst.CONTENT_TYPE)));
            if (flag) {
                response.writeBody(savePath);
                imgInfoMapper.insert(imgInfo);
                return getImgResource(request,imgInfo.getImgRoute());
            }
        }catch (Exception e){
            log.error("获取图标失败");
        }

        return getImgResource(request,null);
    }


    private ResponseEntity<InputStreamResource> getImgResource(HttpServletRequest request,String imgRoute) throws IOException {
        String address = request.getHeader("referer");//获取页面的请求地址
        String pathAdd = "";//定义空字符串
        if (StrUtil.isNotEmpty(address)) {//判断当前的页面的请求地址为空时
            URL hostUrl = new URL(address);//实例化URL方法
            pathAdd = hostUrl.getHost();//获取请求页面的服务器主机
        }


        boolean flag = Boolean.TRUE;
        for (String white : seobenchConfig.getWhiteUrlList()) {
            if (pathAdd.equals(white)) {
                flag = Boolean.FALSE;
                break;
            }
        }
        HttpHeaders headers = new HttpHeaders();
        if (flag) {//判断当前页面的主机与服务器的主机是否相同
            headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }


        if (StrUtil.isEmpty(imgRoute)) {//判断当前页面的主机与服务器的主机是否相同
            headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }

        Path imagePath = Paths.get(seobenchConfig.getGetfaviconStorage() + imgRoute);
        File file = imagePath.toFile();
        InputStreamResource inputStreamResource = new InputStreamResource(Files.newInputStream(file.toPath()));
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + imgRoute);
        headers.add(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_JPEG_VALUE);
        headers.add(HttpHeaders.ACCEPT,"image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8");
        return ResponseEntity.ok()
                .headers(headers)
                .body(inputStreamResource);
    }


    /**
     * 获取域名
     * @param url 地址
     * @return 域名
     */
    private String getDomainFromUrl(String url) {
        String regex = "^(http[s]?://)?([^/]+)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(url);
        if (matcher.find()) {
            return matcher.group(2);
        }
        return null;
    }
}
